package com.haohope.framework.autoconfigure;

import java.util.Properties;

import javax.sql.DataSource;

import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.RegexpMethodPointcutAdvisor;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import com.alibaba.druid.filter.config.ConfigFilter;
import com.alibaba.druid.filter.encoding.EncodingConvertFilter;
import com.alibaba.druid.filter.logging.CommonsLogFilter;
import com.alibaba.druid.filter.logging.Log4j2Filter;
import com.alibaba.druid.filter.logging.Log4jFilter;
import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import com.haohope.framework.FrameworkApp;
import com.haohope.framework.accesslog.AbstractAccesslog;
import com.haohope.framework.accesslog.DefaultAccesslog;
import com.haohope.framework.datasource.DataSourceStatViewServlet;
import com.haohope.framework.datasource.PrimaryDataSource;
import com.haohope.framework.datasource.RoutingDataSource;
import com.haohope.framework.ureport2.Ureport2Provider;
import com.haohope.framework.ureport2.Ureport2ServiceImpl;
import com.haohope.framework.ureport2.Ureport2Servlet;
import com.haohope.framework.wb.FrameworkWbUtil;
import com.wb.auth.DataAuth;
import com.wb.common.Base;
import com.wb.common.Dictionary;
import com.wb.common.FileBuffer;
import com.wb.common.KVBuffer;
import com.wb.common.UserList;
import com.wb.common.Var;
import com.wb.common.WebSocket;
import com.wb.common.XwlBuffer;
import com.wb.interact.Controls;

/**
 * @author lihengming [89921218@qq.com]
 */
@Configuration
@ImportResource({ "classpath:ureport2-console-context.xml" })
public class FrameworkAutoConfigure {
	/////////////////////////////////main
	@Bean
	public FrameworkApp frameworkApp() {
		return new FrameworkApp();
	}
	@Bean(name = "primaryDataSource")
	@Primary
	public DataSource datasource() {
		return new PrimaryDataSource();
	}
	@Bean(name = "primaryJdbcTemplate")
	@Primary
	// @ConditionalOnBean(name = "primaryDataSource")
	public JdbcTemplate jdbcTemplate() {// DataSource dataSource) {
		return new JdbcTemplate(datasource());
	}
	@Bean(name = "routingDataSource")
	// @ConditionalOnBean(name = "primaryDataSource")
	public RoutingDataSource routingDataSource() {// DataSource dataSource,JdbcTemplate jdbcTemplate) {
		return new RoutingDataSource(datasource(), jdbcTemplate());
	}
	@Bean(name = "routingJdbcTemplate")
	// @ConditionalOnBean(name = "routingDataSource")
	public JdbcTemplate routingJdbcTemplate() {// DataSource dataSource) {
		return new JdbcTemplate(routingDataSource());
	}
    /////////////////////////////////main
    /////////////////////////////////wb
	@Bean
	public FrameworkWebServerFactoryCustomizer frameworkWebServerFactoryCustomizer() {
		return new FrameworkWebServerFactoryCustomizer();
	}
	@Bean
	public FilterRegistrationBean<Base> wbFilter() {
		FilterRegistrationBean<Base> filter = new FilterRegistrationBean<Base>();
		filter.setFilter(new Base());
		filter.addUrlPatterns(new String[] { "/*" });
		return filter;
	}
	@Bean
	public AbstractAccesslog accesslog() {
		return new DefaultAccesslog();
	}
	@Bean
	public FrameworkWbUtil wbUtil() {
		return new FrameworkWbUtil();
	}
	@Bean
	public UserList userList() {
		return new UserList();
	}
	@Bean
	public WebSocket webSocket() {
		return new WebSocket();
	}
	@Bean
	public Dictionary dictionary() {
		return new Dictionary();
	}
	@Bean
	public DataAuth dataAuth() {
		return new DataAuth();
	}
	@Bean
	public FileBuffer fileBuffer() {
		return new FileBuffer();
	}
	@Bean
	public KVBuffer kvBuffer() {
		return new KVBuffer();
	}
	@Bean
	public Var var() {
		return new Var();
	}
	@Bean
	public XwlBuffer xwlBuffer() {
		return new XwlBuffer();
	}
	@Bean
	public Controls controls() {
		return new Controls();
	}
    /////////////////////////////////wb
    /////////////////////////////////ureport
	@Bean
	public ServletRegistrationBean<Ureport2Servlet> ureport2Servlet() {
		ServletRegistrationBean<Ureport2Servlet> servlet = new ServletRegistrationBean<Ureport2Servlet>();
		servlet.setServlet(new Ureport2Servlet());
		servlet.addUrlMappings(new String[] { "/ureport/*" });
		return servlet;
	}
	@Bean
	@Primary
	public Ureport2Provider ureport2Provider(JdbcTemplate jdbcTemplate) {// JdbcTemplate jdbcTemplate) {
		return new Ureport2Provider(new Ureport2ServiceImpl(jdbcTemplate));
	}
    /////////////////////////////////ureport
    /////////////////////////////////druid
	private static final String DEFAULT_ALLOW_IP = "127.0.0.1";
	@Bean
	public ServletRegistrationBean<DataSourceStatViewServlet> statViewServletRegistrationBean() {
		Properties properties = System.getProperties();
		ServletRegistrationBean<DataSourceStatViewServlet> registrationBean = new ServletRegistrationBean<DataSourceStatViewServlet>();
		registrationBean.setServlet(new DataSourceStatViewServlet());
		// registrationBean.addUrlMappings(config.getUrlPattern() != null ?
		// config.getUrlPattern() : "/druid/*");
		registrationBean.addUrlMappings("/druid/*");
		{
			String property = properties.getProperty("druid.statview.allow");
			if (property != null && property.length() > 0) {
				registrationBean.addInitParameter("allow", property);
			} else {
				registrationBean.addInitParameter("allow", DEFAULT_ALLOW_IP);
			}
		}
		{
			String property = properties.getProperty("druid.statview.deny");
			if (property != null && property.length() > 0) {
				registrationBean.addInitParameter("deny", property);
			}
		}
		{
			String value = properties.getProperty("druid.statview.resetEnable");// getBoolean(properties,
																				// "druid.statview.resetEnable");
			if (value != null) {
				registrationBean.addInitParameter("resetEnable", value);
			} else {
				registrationBean.addInitParameter("resetEnable", "true");
			}
		}
		return registrationBean;
	}
	@Bean
	public FilterRegistrationBean<WebStatFilter> webStatFilterRegistrationBean() {
		Properties properties = System.getProperties();
		FilterRegistrationBean<WebStatFilter> registrationBean = new FilterRegistrationBean<WebStatFilter>();
		WebStatFilter filter = new WebStatFilter();
		registrationBean.setFilter(filter);
		registrationBean.addUrlPatterns("/*");
		registrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
		{
			String property = properties.getProperty("druid.statfilter.sessionStatEnable");
			if (property != null && property.length() > 0) {
				registrationBean.addInitParameter("sessionStatEnable", property);
			} else {
				registrationBean.addInitParameter("sessionStatEnable", "true");
			}
		}
		{
			String property = properties.getProperty("druid.statfilter.sessionStatMaxCount");
			if (property != null && property.length() > 0) {
				registrationBean.addInitParameter("sessionStatMaxCount", property);
			}
		}
		{
			String property = properties.getProperty("druid.statfilter.principalSessionName");
			if (property != null && property.length() > 0) {
				registrationBean.addInitParameter("principalSessionName", property);
			}
		}
		{
			String property = properties.getProperty("druid.statfilter.principalCookieName");
			if (property != null && property.length() > 0) {
				registrationBean.addInitParameter("principalCookieName", property);
			}
		}
		{
			String property = properties.getProperty("druid.statfilter.profileEnable");
			if (property != null && property.length() > 0) {
				registrationBean.addInitParameter("profileEnable", property);
			} else {
				registrationBean.addInitParameter("profileEnable", "true");
			}
		}
		return registrationBean;
	}
	@Bean
	public StatFilter statFilter() {
		return new StatFilter();
	}
	@Bean
	public ConfigFilter configFilter() {
		return new ConfigFilter();
	}
	@Bean
	public EncodingConvertFilter encodingConvertFilter() {
		return new EncodingConvertFilter();
	}
	@Bean
	public Slf4jLogFilter slf4jLogFilter() {
		return new Slf4jLogFilter();
	}
	@Bean
	public Log4jFilter log4jFilter() {
		return new Log4jFilter();
	}
	@Bean
	public Log4j2Filter log4j2Filter() {
		return new Log4j2Filter();
	}
	@Bean
	public CommonsLogFilter commonsLogFilter() {
		return new CommonsLogFilter();
	}
	@Bean
	public WallConfig wallConfig() {
		return new WallConfig();
	}
	@Bean
	public WallFilter wallFilter(WallConfig wallConfig) {
		WallFilter filter = new WallFilter();
		filter.setConfig(wallConfig);
		return filter;
	}
	@Bean
	public Advice advice() {
		return new DruidStatInterceptor();
	}
	@Bean
	public Advisor advisor() {
		String[] aopPatterns = null;
		Properties properties = System.getProperties();
		{
			String property = properties.getProperty("druid.validationQuery");
			if (property != null && property.length() > 0) {
				property += ",com.haohope.*.service.*";
				aopPatterns = property.split(",");
			} else {
				aopPatterns = new String[] { "com.haohope.*.service.*" };
			}
		}
		return new RegexpMethodPointcutAdvisor(aopPatterns, advice());
	}
	@Bean
	public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		advisorAutoProxyCreator.setProxyTargetClass(true);
		return advisorAutoProxyCreator;
	}
    /////////////////////////////////druid
    /////////////////////////////////oauth2
    /////////////////////////////////oauth2
	/**
	 * 解决前后端分离跨域问题
	 *
	 * @return
	 */
	/**
	 * @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource
	 *       source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration
	 *       config = new CorsConfiguration(); config.setAllowCredentials(true);
	 *       config.addAllowedOrigin("*"); config.addAllowedHeader("*");
	 *       config.addAllowedMethod("*");
	 *       source.registerCorsConfiguration("/oauth/*", config); return new
	 *       CorsFilter(source); }
	 **/


}
